package cn.wsalix.shop.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Observable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.anlaser.admin.BaseUser;
import cn.anlaser.form.UploadFileForm;
import cn.anlaser.service.impl.SimpleServiceImpl;
import cn.anlaser.status.DataEnum;
import cn.anlaser.type.FileTypeEnum;
import cn.anlaser.type.ImageTypeEnum;
import cn.anlaser.utils.SearchFilter;
import cn.anlaser.utils.SearchFilter.Operator;
import cn.wsalix.biz.entity.Advertise;
import cn.wsalix.biz.entity.Category;
import cn.wsalix.biz.entity.RelationAd;
import cn.wsalix.biz.entity.RelationCat;
import cn.wsalix.biz.repository.RelationAdRepository;
import cn.wsalix.biz.repository.RelationCatRepository;
import cn.wsalix.biz.type.AdTypeEnum;
import cn.wsalix.biz.type.CatTypeEnum;
import cn.wsalix.observable.service.FileUploadService;
import cn.wsalix.shop.entity.Product;
import cn.wsalix.shop.entity.RelationProduct;
import cn.wsalix.shop.entity.Shop;
import cn.wsalix.shop.form.ShopForm;
import cn.wsalix.shop.repository.RelationProductRepository;
import cn.wsalix.shop.repository.ShopRepository;
import cn.wsalix.shop.service.ShopService;
import cn.wsalix.shop.status.ShopEnum;
import cn.wsalix.shop.type.ProductTypeEnum;
import cn.wsalix.user.entity.UserInfo;
import cn.wsalix.user.service.UserInfoService;

@Service("shopService")
public class ShopServiceImpl extends
		SimpleServiceImpl<ShopForm, ShopRepository, Shop> implements
		ShopService {
	@Autowired
	private ShopRepository shopRepository;
	@Autowired
	private RelationCatRepository relationCatRepository;
	@Autowired
	private RelationAdRepository relationAdRepository;
	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private RelationProductRepository relationProductRepository;

	@Override
	public String module() {
		return "/shop/main";
	}

	@Override
	public ShopRepository getRepository() {
		return shopRepository;
	}

	@Override
	public Class<Shop> getEntityClazz() {
		return Shop.class;
	}

	@Transactional
	public Shop getNew() {
		BaseUser user = userUtils.getUser();
		ShopForm form = new ShopForm();
		form.setFlag(DataEnum.create);
		form.setCreatedBy(user.getId());
		List<Shop> resLst = findByForm(form);
		if (!resLst.isEmpty()) {
			return resLst.get(0);
		} else {
			UserInfo userInfo = userInfoService.findByUser(user.getId());
			Shop obj = new Shop();
			obj.setFlag(DataEnum.create);
			obj.setCreatedBy(user.getId());
			obj = add(obj);
			userInfo.setExistShop(true);
			userInfoService.edit(userInfo);
			return obj;
		}
	}

	@Override
	public Shop add(ShopForm form) {
		Shop obj = shopRepository.findOne(form.getId());
		traversalAssign(form, obj);
		obj.setFlag(DataEnum.valid);
		return add(obj);
	}

	@Override
	public Map<String, SearchFilter> buildByForm(ShopForm form) {
		Map<String, SearchFilter> filters = buildFilter(form);
		if (form.getCode() != null && !form.getCode().equals("")) {
			filters.put("code",
					new SearchFilter("code", Operator.EQ, form.getCode()));
		}
		if (form.getPrincipalId() != null && !form.getPrincipalId().equals("")) {
			filters.put("principal.id", new SearchFilter("principal.id",
					Operator.EQ, form.getPrincipalId()));
		}

		return filters;
	}

	@Transactional
	@Override
	public Shop createShop() {
		Shop shop = getNew();
		return shop;
	}

	@Transactional
	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof FileUploadService) {
			FileUploadService fileUploadService = (FileUploadService) o;
			if (arg instanceof UploadFileForm) {
				UploadFileForm obj = (UploadFileForm) arg;
				if (obj.getType().ordinal() == FileTypeEnum.image.ordinal()) {
					if (obj.getImageType().ordinal() == ImageTypeEnum.shop
							.ordinal()) {
						if (obj.getCode() != null
								&& obj.getCode().equals("logo")) {
							Shop shop = findById(obj.getFkId());
							shop.setLogo(obj.getHttpUrl());
							super.edit(shop);
							// fileUploadService.setObj(product);
						}

					}
				}
			}
		}

	}

	@Transactional
	@Override
	public void addProduct(Long shopId, Product obj) {
		RelationProduct relationProduct = new RelationProduct();
		relationProduct.setFkId(shopId);
		relationProduct.setProductType(ProductTypeEnum.shop);
		relationProduct.setProduct(obj);
		relationProductRepository.save(relationProduct);
	}

	@Transactional
	@Override
	public void delProduct(Long shopId, Long productId) {
		relationProductRepository.deleteBy(shopId, productId,
				ProductTypeEnum.shop);
	}

	@Transactional
	@Override
	public void addCat(Long shopId, Category category) {
		RelationCat relationCat = new RelationCat();
		relationCat.setCategory(category);
		relationCat.setFkId(shopId);
		relationCat.setCatType(CatTypeEnum.shop);
		relationCat.setFlag(DataEnum.valid);
		BaseUser user = userUtils.getUser();
		relationCat.setCreatedBy(user.getId());
		relationCat.setCreatedDate(new Date());
		relationCatRepository.save(relationCat);
	}

	@Transactional
	@Override
	public void delCat(Long shopId, Long catId) {
		relationCatRepository.deleteByCatTypeAndFkid(shopId, catId,
				CatTypeEnum.shop);
	}

	@Transactional
	@Override
	public void addAd(Long shopId, Advertise entity) {
		RelationAd relationAd = new RelationAd();
		relationAd.setAdvertise(entity);
		relationAd.setAdType(AdTypeEnum.shop);
		relationAd.setFkId(shopId);
		relationAd.setFlag(DataEnum.valid);
		BaseUser user = userUtils.getUser();
		relationAd.setCreatedBy(user.getId());
		relationAd.setCreatedDate(new Date());
		relationAdRepository.save(relationAd);
	}

	@Transactional
	@Override
	public void delAd(Long shopId, Long adId) {
		relationAdRepository.deleteByAdTypeAndFkid(shopId, adId,
				AdTypeEnum.shop);
	}

	@Transactional
	@Override
	public void shopReady(Long shopId) {
		Shop shop = findById(shopId);
		shop.setStatus(ShopEnum.ready);
		super.edit(shop);
	}

	@Transactional
	@Override
	public Shop pass(Long shopId) {
		Shop obj = shopRepository.findOne(shopId);
		obj.setStatus(ShopEnum.release);
		return obj;
	}

	@Transactional
	@Override
	public Shop unPass(Long shopId) {
		Shop obj = shopRepository.findOne(shopId);
		obj.setStatus(ShopEnum.unPass);
		return obj;
	}
}
